﻿using System;
using System.Collections.Generic;
using Battle.Engine.InputData;

namespace Battle.Engine.LogicModel
{
    public class FPlayer
    {
        public CampType camp;           //进攻or防守
        public CampType enemyCamp;      //对方的阵营
        public List<FActor> actors;
        public List<FActor> deadActors;
        public int magicStoneNum = 0;
        public int waterBallNum = 0;

        public int level;
        public bool isPlayer;
        public double angerNum;
        public double costAngerInRound;
        public double maxAngerNum;
        public int comboNum;
        public int maxComboNum;//当场战斗达到的最大连击数
        public double comboTimeLast;
        public double comboBreakTime;
        public double totalHp;//初始总血量

        public double damageFactor;
        
        public bool record = false;                             //是否需要记录操作
        public List<FOperateSkill> recordSkills = null;        //是否需要记录操作
        public List<FOperateTrans> recordTranss = null;

        public List<FOperateSkill> replaySkills = null;        //是否需要回放操作
        public List<FOperateTrans> replayTranss = null;


        public EngineData engineData;
        public void init(CampType camp, InPlayerData iplayer, EngineData data)
        {
            this.engineData = data;
            this.camp = camp;
            if (this.camp == CampType.ATTACK)
                this.enemyCamp = CampType.DEFENCE;
            else
                this.enemyCamp = CampType.ATTACK;
            this.level = iplayer.level;
            this.isPlayer = iplayer.isPlayer;
            this.angerNum = iplayer.angerNum;
            this.costAngerInRound = 0;
            this.maxAngerNum = data.tableDataUtil.GetFighterMaxAnger();

            this.comboNum = 0;
            this.maxComboNum = 0;
            this.comboTimeLast = 0;
            this.comboBreakTime = this.engineData.tableDataUtil.GetComboBreakTime();

            this.totalHp = 0;
            this.damageFactor = iplayer.damageFactor;

            this.actors = new List<FActor>();
            foreach (var iactor in iplayer.actors)
            {
                FActor actor = new FActor();
                actor.init(this, iactor, this.engineData);
                if(actor.attribute.hp > 0)
                {
                    this.totalHp += actor.attribute.hp;
                }
                actors.Add(actor);
            }
            this.deadActors = new List<FActor>();
            this.magicStoneNum = 0;
            this.waterBallNum = 0;
        }

        public void AddAnger(double anger, FActor actor, FExportOnceData exportOnceData)
        {//实际存储和展示的怒气值都为int
            if (anger == 0)
                return;
            if(anger > 0)
            {
                anger = anger * actor.attribute.angerRate;
                if(anger <= 0)
                {
                    return;
                }
            }
            double exportVal = anger;
            if((this.angerNum + anger) < 0)
            {
                exportVal = 0 - this.angerNum;
                this.angerNum = 0;
            }
            else if ((this.angerNum + anger) > maxAngerNum)
            {
                exportVal = maxAngerNum - this.angerNum;
                this.angerNum = maxAngerNum;
            }
            else
            {
                exportVal = anger;
                this.angerNum += anger;
            }
            if(exportVal < 0)
            {
                costAngerInRound -= exportVal;
            }
            Debug.LogFightMsg("--------AddAnger:camp" + this.camp + "===> + " + exportVal + " = " + this.angerNum);
            FExportValue exportAngerValue = new FExportValue();
            exportAngerValue.Init(exportOnceData.source, actor, ExportValueClass.ANGER, exportVal);
            exportOnceData.values.Add(exportAngerValue);
        }

        public void AddComboNum(int combo)
        {
            this.comboNum += combo;
            this.comboTimeLast = this.engineData.roundTime;
            if (this.comboNum > this.maxComboNum)
            {
                this.maxComboNum = this.comboNum;
            }
        }

        public double GetComboHitDamageFactor()
        {
            double factorCount = this.comboNum/this.engineData.tableDataUtil.GetCombohitAddNum();
            double factor = this.engineData.tableDataUtil.GetCombohitdamageFactor() * CommonMethod.tableAttributeConvert * Math.Floor(factorCount);
            return factor;
        }

        //当前有多少人正在释放技能
        public int GetSkillingActorNum()
        {
            int count = 0;
            foreach(var actor in this.actors)
            {
                if(actor.doSkill!=null || actor.doUltimateSkill != null)
                {
                    count++;
                }
            }
            return count;
        }

        public void ResetRound(EngineData data)
        {
            this.costAngerInRound = 0;
            BreakCombo();
            foreach (var actor in actors)
            {
                actor.ResetRound(data);
            }
        }
        public void SkillEnd(FSkill skill)
        {
            if (skill.IsUltimate)
            {
                BreakCombo();
            }

        }
        public void BreakCombo()
        {
            comboTimeLast = this.engineData.roundTime;
            if (this.comboNum == 0)
                return;
            this.comboNum = 0;
            foreach (var actor in this.actors)
            {
                actor.selfComboNum = 0;
            }
            if (this.engineData.callback != null)
                this.engineData.callback.BreakCombo("");

        }

        public void Update(EngineData data)
        {
            bool isDoUltimateSkill = false;
            foreach (var actor in actors)
            {
                actor.Update(data);
                if(isDoUltimateSkill == false && actor.doUltimateSkill != null)
                {
                    isDoUltimateSkill = true;
                }
                
            }
            if (data.roundTime - this.comboTimeLast >= this.comboBreakTime)
            {
                foreach (var actor in this.actors)
                {
                    if (actor.doSkill != null)
                    {
                        return;
                    }
                }
                if (!isDoUltimateSkill)
                {
                    BreakCombo();
                }
            }
        }

        public FActor GetActorByUID(string uid)
        {
            foreach (var actor in actors)
            {
                if (actor.uniqueId == uid)
                    return actor;
            }
            return null;
        }

        public FActor GetActorByFpid(int fpid, FActor tactor, List<SelectLimitCondition> conditions, EngineData data)
        {
            foreach (var actor in actors)
            {
                if (actor.IsDetectionPosition(fpid))
                {
                    if (data.IsActorMatchCondition(actor, tactor, conditions))
                    {//判断是否满足限制条件
                        return actor;
                    }
                }
            }
            return null;
        }
    }
}
